var app;
var max = Math.max;
var floor = Math.floor;
function nextexp(level) { return level >= 1 ? floor(10 + level * level * 5) : 0; }
function O(id) { return document.getElementById(id); }

function PokeMon(attrs) {
    this.level = 1;
    this.maxhp = this.hp = attrs.hp;
    this.maxmp = this.mp = attrs.mp || 0;
    this.atk = attrs.atk;
    this.exp = attrs.exp || 0;
    this.mpcost = attrs.mpcost || 0;
}
PokeMon.prototype.attack = function(other) {
    other.hp = floor(max(0, other.hp - this.atk));
}
PokeMon.prototype.magicTo = function(other) {
    if (this.mp >= this.mpcost) {
        other.hp = floor(max(0, other.hp - this.atk * 1.8));
        this.mp -= this.mpcost;
        return true;
    } else {
        return false
    }
}
PokeMon.prototype.guard = function(other) {
    var atk = Math.max(1, other.atk * 0.2);
    this.hp = Math.max(0, this.hp - atk);
}
PokeMon.prototype.gainExp = function(exp) {
    var isLevelUp = false;
    this.exp += exp;
    while (this.exp >= nextexp(this.level)) {
        this.level ++;

        this.maxhp += floor(this.level * 2.75);
        this.hp = this.maxhp;
        this.maxmp += floor(this.level * 2.25);
        this.mp = this.maxmp;

        this.atk += floor(this.level * 1.25);
        isLevelUp = true
    }
    return isLevelUp;
}
PokeMon.prototype.heal = function(exp) {
    this.hp = this.maxhp;
    this.mp = this.maxmp;
}

var my = new PokeMon({hp: 100, atk:10, mp:100, mpcost:10});
var enemy = new PokeMon({hp:100, atk:12, exp:12});

function meetEnemy() {
    enemy = new PokeMon({hp:100, atk:12, exp:12});
    app.enemy = enemy;
    app.scene = 'fight';
}

function attack() {
    my.attack(enemy);
    enemy.hp > 0 && enemy.attack(my);
    console.log("Attack!", my, enemy);
    checkHp();
}

function magicTo() {
    my.magicTo(enemy);
    enemy.hp > 0 && enemy.attack(my);
    console.log("Magic!", my, enemy);
    checkHp();
}

function guard() {
    my.guard(enemy);
    console.log("Guard!", my, enemy);
    checkHp();
}

function checkHp() {
    if (my.hp == 0) {
        console.log('My die ...');
        app.msg = 'Loose...'
        enemy = null;
        setTimeout(backToMap, 3000);
    }
    else if (enemy.hp == 0) {
        var 
        var level = app.my.level;
        app.levelup = my.gainExp(enemy.exp);
        if (app.levelup) { app.msg = '<-'+level; console.log('levelup'); }
        console.log('Win!!!!', my);
        app.msg += 'Win!';
        enemy = null;
        setTimeout(backToMap, 3000);
    }
}

function backToMap() {
    app.scene = 'map';
    app.msg = '';
}

function handleInput(keyName) {
    if (keyName == 'n') {
        meetEnemy();
        console.log('meet enemy!', my, enemy);
    } else if (keyName == 'i') {
        my.heal();
        console.log('Sleeped!', my);
    } else if (enemy) {
        if (keyName == 'a') { attack(); } 
        else if (keyName == 'm') { magicTo(); }
        else if (keyName == 'g') { guard(); }
    } else {
        console.log('press n to meet an emeny, i to heal in inn', my);
    }
}

document.onkeyup = function (e) {
    var keyName = e.key;
    console.log(keyName);
    handleInput(keyName);
}

//===View===
window.onload = function() {
    app = new Vue({
        el: '#app',
        data: {
            my: my,
            enemy: enemy,
            scene: 'map',
            levelup: false,
            msg: ''
        },
        methods: {
            curhp: function(pokeMon) { return pokeMon.hp * 100 / (pokeMon.maxhp+0.00001); },
            curmp: function(pokeMon) { return pokeMon.mp * 100 / (pokeMon.maxmp+0.00001); },
            curexp: function(pokeMon) { return (pokeMon.exp-nextexp(pokeMon.level-1)) * 100 / (nextexp(pokeMon.level)-nextexp(pokeMon.level-1)+0.00001); }
        }
    });
}
